﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.Text;
using System.Collections.Generic;

namespace jacSocketClient
{
    public class ClientControler
    {
        private System.Threading.SynchronizationContext ui;

        private Socket _socket;

        private MessageStream stream;

        IProcessor Client;

        public ClientControler(string SvIP,int Sport, IProcessor client)
        {
            ui = System.Threading.SynchronizationContext.Current;

            this.Client = client;

            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            stream = new MessageStream();

            SocketAsyncEventArgs args = new SocketAsyncEventArgs();
            
            args.RemoteEndPoint = new DnsEndPoint(SvIP, Sport);

            args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSocketConnectCompleted);

            _socket.ConnectAsync(args);
        }

        private void OnSocketConnectCompleted(object sender, SocketAsyncEventArgs e)
        {
            byte[] response = new byte[1024];
            e.SetBuffer(response, 0, response.Length);

            e.Completed -= new EventHandler<SocketAsyncEventArgs>(OnSocketConnectCompleted);
            e.Completed += new EventHandler<SocketAsyncEventArgs>(OnSocketReceiveCompleted);

            _socket.ReceiveAsync(e);

            ui.Post(this.Client.connetData, _socket.Connected);
        }

        private void OnSocketReceiveCompleted(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                this.stream.Write(e.Buffer, e.Offset, e.BytesTransferred);
                Message message;
                while (stream.Read(out message))
                {
                    string data = UTF8Encoding.UTF8.GetString(message.Content, 0, message.Size);
                    ui.Post(this.Client.ProcessData, data);
                }
            }
            catch (Exception ex)
            {
                ui.Post(this.Client.OnError, ex.Message);
            }

            _socket.ReceiveAsync(e);
        }

        public void SendData(string msg)
        {
            if (_socket.Connected)
            {
                SocketAsyncEventArgs myMsg = new SocketAsyncEventArgs();
                myMsg.RemoteEndPoint = _socket.RemoteEndPoint;
                Message message = new Message(1, 1, UTF8Encoding.UTF8.GetBytes(msg));
                byte[] buffer = message.ToBytes();
                myMsg.SetBuffer(buffer, 0, buffer.Length);

                _socket.SendAsync(myMsg);
            }
            else
            {
                string err = "can't connet to server!";
                _socket.Close();
                ui.Post(this.Client.OnError, err);
            }
        }
    }
}
